#pragma once

#include "Renderer.h"
#include "common/Types.h"

#include "sfml/Graphics/RenderWindow.hpp"

class ApplicationEventObserver
{
public:
	virtual ~ApplicationEventObserver() {}

	virtual void	OnKeyDown(sf::Key::Code /*keyCode*/) {}
	virtual void	OnKeyUp(sf::Key::Code /*keyCode*/) {}
	virtual void	OnIdle() {}
	virtual void	OnPaint() {}
};

namespace sf { class Font; }
typedef sf::Font	Font;

class Application : public Renderer
{
public:
	explicit Application(bool fullscreen = false);
	~Application();

	// SETTERS
	void	SetObserver(ApplicationEventObserver* observer);
	void	SetBackgroundColour(float red, float green, float blue, float alpha);

	// BUSINESS METHODS
	void	Run();

	// RENDERER INTERFACE IMPLEMENTATION
	virtual void	Render();
	virtual void	RenderLine(const Vector2& start, const Vector2& end);
	virtual void	RenderCircle(const Vector2& position, phynet::Real radius, phynet::UInt numSegments);
	virtual void	RenderBox(const Vector2& p1, const Vector2& p2,
							const Vector2& p3, const Vector2& p4);
	virtual void	RenderText(const char* text, const Vector2& position);
	virtual void	RenderTextLine(const char* text);
	virtual void	Prepare2DViewport(int left, int top, int width, int height);
	virtual void	Prepare3DViewport(int left, int top, int width, int height);

private:
	void	OnResize(unsigned int width, unsigned int height);
	
	void	Init();
	void	Init3D();
	void	Init2D();

	sf::RenderWindow*			m_window;
	ApplicationEventObserver*	m_eventObserver;

	Font*						m_font;
	phynet::UInt		m_fontSize;

	bool						m_is3D;

	// background color
	float 						m_red;
	float 						m_green;
	float 						m_blue;
	float 						m_alpha;

	Vector2						m_nextTextLinePosition;
}; // class Application
